package com.jtw.common.util;

import com.jtw.common.bean.enums.HeadImageType;
import com.jtw.common.bean.enums.ReqCode;
import com.jtw.common.constants.CommonSysConstant;
import com.jtw.common.orderGenerator.SnowFlake;
import lombok.extern.slf4j.Slf4j;
import net.coobird.thumbnailator.Thumbnails;
import org.apache.commons.fileupload.FileItemIterator;
import org.apache.commons.fileupload.FileItemStream;
import org.apache.commons.fileupload.FileUploadException;
import org.apache.commons.fileupload.servlet.ServletFileUpload;
import org.apache.commons.io.IOUtils;
import org.apache.tika.exception.TikaException;
import org.apache.tika.metadata.HttpHeaders;
import org.apache.tika.metadata.Metadata;
import org.apache.tika.metadata.TikaMetadataKeys;
import org.apache.tika.mime.MediaType;
import org.apache.tika.parser.AutoDetectParser;
import org.apache.tika.parser.ParseContext;
import org.apache.tika.parser.Parser;
import org.xml.sax.SAXException;
import org.xml.sax.helpers.DefaultHandler;

import javax.servlet.http.HttpServletRequest;
import java.io.*;
import java.util.*;

/**
 * DESCRIPT:
 *
 * @author cjsky666
 * @date 2018/11/19 15:22
 */
@Slf4j
public class UploadUtil {
    public static final double KEY_THUMB_NAIL_QUALITY = 0.4;
    public static final int KEY_THUMB_NAIL_W = 64;
    public static final int KEY_THUMB_NAIL_H = 64;
    SnowFlake snowFlake = new SnowFlake(1, 2);
    public static final String KEY_FILE_NAME = "imagePath";
    public static final String KEY_THUMB_NAIL_IMAGE_NAME = "thumbNailImagePath";

    /**
     * 批量及单个上传文件,不生成缩略图
     *
     * @param resultList
     * @param iter
     * @param saveHeadImagePath
     * @param saveHeadThumbNailImagePath
     * @return
     * @throws IOException
     * @throws FileUploadException
     */
    public static List<String> UploadFileOrImageNoThumbNail(List<String> resultList, HttpServletRequest request, String fileSaveDirectory,String fileSavePath) throws IOException, FileUploadException, TikaException, SAXException {

        boolean isMultipart = ServletFileUpload.isMultipartContent(request);
        if (!isMultipart) {
            throw ReqCode.UploadFileNoExist.getException();
        }
        ServletFileUpload upload = new ServletFileUpload();
        FileItemIterator iter = upload.getItemIterator((HttpServletRequest) request);

        while (iter.hasNext()) {
            FileItemStream item = iter.next();
            String name = item.getFieldName();
            InputStream stream = item.openStream();
            String savaPath = CommonSysConstant.KEY_FILE_PATH_SEPARATOR + DateUtil.format(Calendar.getInstance().getTime(), DateUtil.YMD);

            String suffix = getSuffixName(item.getName());
            //文件名称
//                qweqweqy12312371nahsdkjh
            String fileName = UUID.randomUUID().toString().replace("-", "");

            //生成文件夹保存路径
//                e://asdasdas/resources/static/20180801
            File dir = new File(fileSaveDirectory + savaPath);
            if (!dir.exists()) {
                dir.mkdirs();
            }
//                /20180801/abc.jpg
            String imageSavePath =  savaPath+ CommonSysConstant.KEY_FILE_PATH_SEPARATOR+fileName+"."+suffix;
//                  /20180801/abcthumbnail.jpg
            String thumbImageSavePath =  savaPath+ CommonSysConstant.KEY_FILE_PATH_SEPARATOR+fileName+"thumbnail"+"."+suffix;
//                e://asdasdas/resources/static"+ /20180801/abc.jpg
            File file = new File(fileSaveDirectory + imageSavePath);
//                /resources/static/20180801/abc.jpg

            OutputStream out = new FileOutputStream(fileSaveDirectory+imageSavePath);

            IOUtils.copy(stream, out);

            String type = getMimeType(new File(fileSaveDirectory+ imageSavePath));

            log.info(type);

            if (!checkFileType(type)) {
                throw ReqCode.UploadFileTypeError.getException();
            }
            stream.close();
            out.close();
            resultList.add(fileSavePath+imageSavePath);
        }
        return resultList;
    }

    /**
     * 多个文件上传,生成缩略图
     *
     * @param resultList
     * @param iter
     * @param saveHeadImagePath
     * @param saveHeadThumbNailImagePath
     * @param enums
     * @return
     * @throws IOException
     * @throws FileUploadException
     */
    public static List<Map<String, String>> UploadImageAndCreateThumbNailImage(List<Map<String, String>> resultList, HttpServletRequest request, String fileSaveDirectory,String fileSavePath,Integer img_w,Integer img_h) throws IOException, FileUploadException, TikaException, SAXException {

        boolean isMultipart = ServletFileUpload.isMultipartContent(request);
        if (!isMultipart) {
            throw ReqCode.UploadFileNoExist.getException();
        }
        ServletFileUpload upload = new ServletFileUpload();
        FileItemIterator iter = upload.getItemIterator((HttpServletRequest) request);
        while (iter.hasNext()) {
            FileItemStream item = iter.next();
            String name = item.getFieldName();
            InputStream stream = item.openStream();
            if (!item.isFormField()) {
                Map<String,String> map = new HashMap<String,String>();
                //存储的文件前缀路径
//                "/20180801"
                String savaPath = CommonSysConstant.KEY_FILE_PATH_SEPARATOR + DateUtil.format(Calendar.getInstance().getTime(), DateUtil.YMD);

                //文件后缀
//                "\\jpg"
                String suffix = getSuffixName(item.getName());
                //文件名称
//                qweqweqy12312371nahsdkjh
                String fileName = UUID.randomUUID().toString().replace("-", "");

                //生成文件夹保存路径
//                e://asdasdas/resources/static/20180801
                File dir = new File(fileSaveDirectory + savaPath);
                if (!dir.exists()) {
                    dir.mkdirs();
                }
//                /20180801/abc.jpg
                String imageSavePath =  savaPath+ CommonSysConstant.KEY_FILE_PATH_SEPARATOR+fileName+"."+suffix;
//                  /20180801/abcthumbnail.jpg
                String thumbImageSavePath =  savaPath+ CommonSysConstant.KEY_FILE_PATH_SEPARATOR+fileName+"thumbnail"+"."+suffix;
//                e://asdasdas/resources/static"+ /20180801/abc.jpg
                File file = new File(fileSaveDirectory + imageSavePath);
//                /resources/static/20180801/abc.jpg
                map.put(KEY_FILE_NAME, fileSavePath+imageSavePath);

                OutputStream out = new FileOutputStream(fileSaveDirectory+imageSavePath);

                IOUtils.copy(stream, out);

                String type = getMimeType(new File(fileSaveDirectory+ imageSavePath));


                if (!checkFileType(type)) {
                    throw ReqCode.UploadFileTypeError.getException();
                }
                stream.close();
                out.close();
                if(img_w == null){
                    img_w = KEY_THUMB_NAIL_W;
                }

                if (img_h == null){
                    img_h = KEY_THUMB_NAIL_H;
                }
                map.put(KEY_THUMB_NAIL_IMAGE_NAME, fileSavePath+thumbImageSavePath);

                Thumbnails.of(fileSaveDirectory + imageSavePath)
                        .size(img_w, img_h)
                        .keepAspectRatio(false)
                        .outputQuality(KEY_THUMB_NAIL_QUALITY)
                        .toFile(fileSaveDirectory + thumbImageSavePath);
                resultList.add(map);
            }
        }
        return resultList;
    }


    /**
     * 检测当前上传的文件类型是否正确
     *
     * @param type
     * @return
     */
    public static boolean checkFileType(String type) {
        boolean flag = false;
        for (HeadImageType s : HeadImageType.values()) {
            if (s.getValue().equals(type)) {
                flag = true;
            }
        }
        return flag;
    }

    /**
     * 获取后缀名
     *
     * @return
     */
    public static String getSuffixName(String filename) {
        String [] names = filename.split("\\.");
        log.info("当前文件的后缀名是-------" + names[names.length-1]);
        return names[names.length-1];
    }

    /**
     * 获取文件的真实类型
     *
     * @param file
     * @return
     */
    private static String getMimeType(File file) throws IOException, TikaException, SAXException {
        AutoDetectParser parser = new AutoDetectParser();
        parser.setParsers(new HashMap<MediaType, Parser>());

        Metadata metadata = new Metadata();
        metadata.add(TikaMetadataKeys.RESOURCE_NAME_KEY, file.getName());
        InputStream stream =null;
        stream = new FileInputStream(file);
        parser.parse(stream, new DefaultHandler(), metadata, new ParseContext());
        stream.close();

        log.info(metadata.get(HttpHeaders.CONTENT_TYPE));

        return metadata.get(HttpHeaders.CONTENT_TYPE);
    }

    public static void main(String[] args) throws TikaException, IOException, SAXException {
//        File file = new File("C:\\Users\\msi-pc\\Desktop\\360.jpg");
        log.info(System.getProperty("user.dir"));

        Thumbnails.of("abc.jpg")
                .scale(0.35f)
                .outputQuality(0.1f)
                .toFile(new File("123.jpg"));
//        getMimeType(file);
    }
}
